/************************************************************************
 * SMLib - State Model Library
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     
 * Description  :     
 * Change log   :     
 * To Do        :
 ************************************************************************/
using System;
using SMLib.Automata.Base;
using System.Collections.Generic;
using SMLib.Automata.DFA;


namespace SMLib.Automata.DFA
{
	/// <summary>
	/// Read DFA traces
	/// </summary>
	public class DFA_Traces
	{
		/// <summary>
		/// Verify the specified machine on negative and positive traces
		/// </summary>
		/// <param name="machine">Machine.</param>
		/// <param name="posSeqs">Position traces</param>
		/// <param name="negSeqs">Negative traces</param>
		public static bool Verify (DFA machine, List<Word> posSeqs, List<Word> negSeqs)
		{
			bool error = false;
			foreach (Word w in posSeqs) {
				if (!machine.IsAccepted (w)) {
					Console.WriteLine ("Error: " + w + " should be accepted but it is rejected on the machine!");
					error = true;
				}
			}
			foreach (Word w in negSeqs) {
				if (machine.IsAccepted (w)) {
					Console.WriteLine ("Error: " + w + " should be rejected but it is accepted on the machine!");
					error = true;
				}
			}
			return error;
		}

		public static void ReadInputFile 
			(string filePath, ref List<Word> posSeqs, ref List<Word> negSeqs, ref Alphabet alph)
		{
			alph = new Alphabet ();
			negSeqs = new List<Word> ();
			posSeqs = new List<Word> ();

			System.IO.StreamReader sr = new System.IO.StreamReader (filePath);
			string line;

			while ((line=sr.ReadLine())!=null) {
				Word sq = new Word ();
				bool sign = line.StartsWith ("+");
				string w = line.Substring (2, line.Length - 2);
				if (w.Length != 0) {
					string[] syms = w.Split (new char[] { ' ' });
					for (int i=0; i<syms.Length; i++) {
						StringSymbol sym = new StringSymbol (syms [i]);
						sq.AddSymbol (sym);

						if (!alph.Contains (sym))
							alph.AddSymbol (sym);
					}
				}
				if (sign)
					posSeqs.Add (sq);
				else
					negSeqs.Add (sq);
			}
		}

		/// <summary>
		/// Reads the input (in Abbadingo data format)
		/// </summary>
		/// <param name="filePath">File path.</param>
		public static void ReadInputFile_AbbadingoFormat 
			(string filePath, ref List<Word> posSeqs, ref List<Word> negSeqs, ref Alphabet alph)
		{
			alph = new Alphabet ();
			negSeqs = new List<Word> ();
			posSeqs = new List<Word> ();

			System.IO.StreamReader sr = new System.IO.StreamReader (filePath);
			string line;
			//* first line is the statistics
			sr.ReadLine ();
			//* from second line data is started
			while ((line=sr.ReadLine())!=null) {
				Word sq = new Word ();
				bool sign = line.StartsWith ("1");
				int secondSpace = line.IndexOf (' ', 2);
				string w = line.Substring (secondSpace + 1, line.Length - (secondSpace + 1));
				if (w.Length != 0) {
					string[] syms = w.Split (new char[] { ' ' });
					for (int i=0; i<syms.Length; i++) {
						if (syms [i] == "")
							continue;
						StringSymbol sym = new StringSymbol (syms [i]);
						sq.AddSymbol (sym);

						if (!alph.Contains (sym))
							alph.AddSymbol (sym);
					}
				}
				if (sign)
					posSeqs.Add (sq);
				else
					negSeqs.Add (sq);
			}
		}
	}
}